package recompiled;

/**
 * TARGET PC: 0xA0000094
 */
public class A0000094 extends compiler.BasicBlock {

	private static final A0000094 INSTANCE = new A0000094();

	private A0000094(){}

	/**
	 * @see compiler.BasicBlock#getBasicBlock 
	 */
	public static compiler.BasicBlock getBasicBlock() {
		return INSTANCE;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void execute() throws mips.exceptions.MipsException {

		//0xa0000094 
		//0x8fc20028 
		//LW
		mips.CPU.GPR[2] = n64.MemoryManager.readWord(mips.CPU.GPR[30] + 40);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa0000098 
		//0x00000020 
		//NOP
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa000009c 
		//0x2442ffff 
		//ADDIU
		u32_gpr_rs = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[2]); 
		
		mips.CPU.GPR[2] = (int)((u32_gpr_rs + -1) & 4294967295L);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000a0 
		//0x00402020 
		//ADD
		u32_gpr_rs = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[2]);
		u32_gpr_rt = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[0]);
		
		if (u32_gpr_rs + u32_gpr_rt > 4294967295L) {
			throw new mips.exceptions.OverflowException(mips.CPU.PC,0x00402020);
		} 
		else {
			mips.CPU.GPR[4] = mips.CPU.GPR[2] + mips.CPU.GPR[0];
		}
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000a4 
		//0x0c000010 
		//JAL
		mips.CPU.GPR[31] = mips.CPU.PC + 8;
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = (mips.CPU.nPC & 0xF0000000) | 0x00000040;


		if(!skipDelaySlot) {
			//0xa00000a8 
			//0x00000020 
			//NOP
			mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;

		}
		
	}

	public static int instructionLength = 6;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int blockLength() {
		int returnLen = instructionLength;
		if(skipDelaySlot) {
			returnLen -= 1;
			skipDelaySlot = false;
		}
		return returnLen;
	}
}

